package cn.edu.sbs.talent.shiro.realm;

import cn.edu.sbs.talent.shiro.service.impl.AccountService;
import cn.edu.sbs.talent.shiro.service.impl.PermissionService;
import cn.edu.sbs.talent.shiro.service.impl.RoleService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Set;

public class TalentRealm extends AuthorizingRealm {
    @Autowired
    @Lazy
    private AccountService accountService;
    @Autowired
    @Lazy
    private RoleService roleService;
    @Autowired
    @Lazy
    private PermissionService permissionService;

    /**
     * 获取认证信息
     *
     * @param token TOKEN
     * @return 认证信息 (含用户名、密码等)
     * @throws AuthenticationException 认证异常，包括未知用户、密码错误等
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        if (token.getPrincipal() == null) {
            return null;
        }

        String username = token.getPrincipal().toString();
        cn.edu.sbs.talent.shiro.entity.Account account = accountService.loadUserByUsername(username);
        if (ObjectUtils.isEmpty(account)) {
            throw new UnknownAccountException();
        }
        if (!StringUtils.hasLength(account.getPassword())) {
            return null;
        }
        if (!account.isEnabled() || account.getDeleted()){
            throw new LockedAccountException();
        }

        account.setLoggedIn(true);
        accountService.save(account);

        return new SimpleAuthenticationInfo(username, account.getPassword(), getName());
    }

    /**
     * 获取权限表
     *
     * @param principalCollection 账户集合
     * @return 授权信息 (含权限表)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取当前用户的所有权限
        String username = principalCollection.getPrimaryPrincipal().toString();
        Set<String> roles = roleService.listNameByAccount(username);
        Set<String> permissions = permissionService.listAuthorizedUrlByAccount(username);

        // 将权限放入授权信息中
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setRoles(roles);
        info.setStringPermissions(permissions);
        return info;
    }

}
